﻿using System;
using Engine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace EngineDrawer.Sky
{
    public class SkyDomeDrawer : DrawableGameComponent
    {
        #region Constructors

        public SkyDomeDrawer(Game game, string skyDomeAssetName, string skyTextureName)
            : base(game)
        {
            _skyDomeModel = game.Content.Load<Model>(skyDomeAssetName);
            SkyTextureName = skyTextureName;
        }

        #endregion

        #region Fields

        readonly private Model _skyDomeModel;
        private Texture2D _texture;
        private World _world;
        private Matrix _skyWorldMatrix;
        private Matrix _perspectiveMatrix;
        private Vector3 _scale;

        #endregion

        #region Properties

        private string _skyTextureName;
        public string SkyTextureName
        {
            get { return _skyTextureName; }
            set 
            { 
                _skyTextureName = value;
                _texture = Game.Content.Load<Texture2D>(value);
            }
        }

        #endregion
        
        #region Override

        public override void Initialize()
        {
            base.Initialize();

            _world = (World)Game.Services.GetService(typeof (World));
            
            float size = Math.Max(_world.Terrain.VertexCountX, _world.Terrain.VertexCountZ)*
                         _world.Terrain.Parameters.BlockSize;

            _scale = new Vector3((size) / _skyDomeModel.Meshes[0].BoundingSphere.Radius);                        
            _perspectiveMatrix = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45), GraphicsDevice.Viewport.AspectRatio, 0.1f, 100000f);           
        }
        public override void Update(GameTime time)
        {
            const float skyRotationSpeed = 0.009f;
            const float domeTranslationY = -0.05f;
            _skyWorldMatrix = Matrix.CreateRotationY((float) time.TotalGameTime.TotalSeconds*skyRotationSpeed)*
                              Matrix.CreateTranslation(0, domeTranslationY, 0)*
                              Matrix.CreateScale(_scale);
            base.Update(time);
        }

        public override void Draw(GameTime time)
        {
            GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;

            foreach (ModelMesh modelMesh in _skyDomeModel.Meshes)
            {
                foreach (BasicEffect basicEffect in modelMesh.Effects)
                {
                    basicEffect.Texture = _texture;             
                    basicEffect.TextureEnabled = true;                           
                    basicEffect.World = _skyWorldMatrix;
                    basicEffect.View = _world.ViewMatrix;
                    basicEffect.Projection = _perspectiveMatrix;
                }
                modelMesh.Draw();
            }
            base.Draw(time);
        }

        #endregion
    }
}
